package com.qd.p2p.web.action.additional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Qualifier;

import com.google.common.base.Splitter;
import com.opensymphony.xwork2.ModelDriven;
import com.qdlc.p2p.biz.service.BaseGiveAwardService;
import com.qdlc.p2p.biz.service.CollectPayService;
import com.qdlc.p2p.biz.service.ReceivingInfoService;
import com.qdlc.p2p.biz.service.UserIdentifyService;
import com.qdlc.p2p.biz.service.UserService;
import com.qdlc.p2p.biz.service.UserWineCouponsService;
import com.qdlc.p2p.biz.service.WineCouponsService;
import com.qdlc.p2p.biz.web.action.BaseAction;
import com.qdlc.p2p.common.constant.BorrowStatus;
import com.qdlc.p2p.common.constant.NotifyUrl;
import com.qdlc.p2p.common.constant.RedUseType;
import com.qdlc.p2p.common.constant.UserWineCouponsStatus;
import com.qdlc.p2p.common.constant.WineCouponsType;
import com.qdlc.p2p.common.constant.WineCouponsUseType;
import com.qdlc.p2p.common.core.ReturnResult;
import com.qdlc.p2p.common.enums.EnumWineCouponsIdsType;
import com.qdlc.p2p.common.exception.WineCouponsException;
import com.qdlc.p2p.common.util.MessageUtil;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.dal.common.model.jpa.QueryParam;
import com.qdlc.p2p.dal.dao.AdditionalCommodityDao;
import com.qdlc.p2p.dal.dao.BorrowDao;
import com.qdlc.p2p.dal.dao.UserWineCouponsDao;
import com.qdlc.p2p.dal.dto.AdditionalCommodity;
import com.qdlc.p2p.dal.dto.Borrow;
import com.qdlc.p2p.dal.dto.TppTradeLog;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.UserIdentify;
import com.qdlc.p2p.dal.dto.UserWineCoupons;
import com.qdlc.p2p.dal.model.BaseGiveAwardModel;
import com.qdlc.p2p.dal.model.UserWineCouponsModel;
import com.qdlc.p2p.dal.util.UserTypeUtils;
import com.qdlc.p2p.dal.util.UserUtils;

/**
 * 酒券
 *
 * @author ygw
 * @version 1.1.0.0
 * @date 2016年5月6日 上午11:16:47
 */
public class UserWineCouponsAction extends BaseAction<UserWineCouponsModel> implements ModelDriven<UserWineCouponsModel> {

    @Resource
    private UserWineCouponsService userWineCouponsService;

    @Resource
    @Qualifier("wineCouponsCollectService")
    private CollectPayService collectService;

    private UserWineCouponsModel model = new UserWineCouponsModel();

    @Resource
    private UserIdentifyService userIdentifyService;

    @Resource
    private UserService userService;
    
    @Resource
    private ReceivingInfoService receivingInfoService;
    
    @Resource
    private WineCouponsService wineCouponsService;
    
    @Resource
    private UserWineCouponsDao userWineCouponsDao;
    
	@Resource
	@Qualifier("giveUserCommodityService")
	private BaseGiveAwardService giveUserCommodityService;
	
    @Resource
    private AdditionalCommodityDao additionalCommodityDao;
    
    @Resource
    private BorrowDao borrowDao;
    
    public UserWineCouponsModel getModel() {
        return model;
    }

    private Map<String, Object> data = new HashMap<String, Object>();

    /**
     * 获取用户可用酒券列表
     *
     * @throws Exception
     */
    @Action(value = "/wineCoupons/useable", interceptorRefs = {@InterceptorRef("session"), @InterceptorRef("globalStack")})
    public void useable() throws Exception {
        User user = getSessionUser();
        checkInvestUser();
        List<UserWineCouponsModel> list = userWineCouponsService.useableList(user.getUserId());
        data.put("rows", list);
        printJson(getStringOfJpaObj(data));
    }

    /**
     * 初始化用户酒券
     *
     * @throws Exception
     */
    @Action(value = "/wineCoupons/initUseable", interceptorRefs = {@InterceptorRef("session"), @InterceptorRef("globalStack")})
    public void initUseable() throws Exception {
        User user = getSessionUser();
        // 用户可用酒券个数
        int count = userWineCouponsService.userableCount(user.getUserId());
        data.put("wineCouponsCount", count);

        printJson(getStringOfJpaObj(data));
    }

    /**
     * 我的酒券页面
     *
     * @return
     * @throws Exception
     */
    @Action(value = "/member/redpacket/availableWineCoupons", results = {@Result(name = "availableWineCoupons", type = "ftl", location = "/member/redpacket/availableWineCoupons.html"),
            @Result(name = "availableWineCoupons_firm", type = "ftl", location = "/member_borrow/redpacket/availableWineCoupons.html")})
    public String availableWineCoupons() throws Exception {
        //checkInvestUser();
        User user = getSessionUser();
        if (UserTypeUtils.isBorrowOrInverstment(user.getUserId())) {
            return "availableWineCoupons_firm";
        }
        return "availableWineCoupons";
    }

    /**
     * 我的酒券数据
     *
     * @throws IOException
     */
    @Action("/member/redpacket/availableWineCouponsJSON")
    public void availableWineCouponsJSON() throws IOException {
        checkInvestUser();
        model.setUserId(getSessionUserId());
        List<UserWineCouponsModel> allList = userWineCouponsDao.getAllList(model);
        data.put("data", allList);
        printWebJson(getStringOfJpaObj(data));
    }

    /**
     * PS 现金酒券兑换现金
     *
     * @throws Exception
     */
    @Action("/member/redpacket/wineCouponsExchange")
    public void wineCouponsExchange() throws Exception {
        User toUser = getSessionUser();

        UserIdentify ui = userIdentifyService.getUserIdentifyByUserId(toUser.getUserId());
        String tppUserCustId = UserUtils.getUserTppCustId(toUser.getUserId());
        if (ui.getRealNameStatus() != 1 || StringUtil.isBlank(tppUserCustId)) {
            throw new WineCouponsException("您还未开通第三方账户，请先开户！", 1);
        }
        long[] wineCouponsIds = model.getWineCouponsIds();
        if (StringUtil.isBlank(wineCouponsIds)) {
        	throw new WineCouponsException("酒券选择有误，请重新选择！", 1);
        }
        
        // 还款后才能使用
        List<Long> ids = getWineCouponsIdList(wineCouponsIds);// 酒券ids
        List<UserWineCoupons> userWineCouponsList = userWineCouponsDao.getWineCouponsByIds(ids);// 酒券List
        // 酒券校验
        for (UserWineCoupons userWineCoupons : userWineCouponsList) {// 不是投标所获的酒券不能兑现
			if (userWineCoupons.getVersion() == 0) {
				throw new WineCouponsException("您的选择存在非投标所获的酒券，请重新选择！", 1);
			}
			// 防止非法篡改
			if (userWineCoupons.getUserId() != toUser.getUserId()) {
				throw new WineCouponsException("所选酒券存在错误，请重新选择！", 1);
			}
		}
        List<Long> borrowIds = getBorrowIdList(userWineCouponsList);// borrowIds
        List<Borrow> borrow = borrowDao.getBorrowByStatusAndIds(BorrowStatus.STATUS_REPAYMENT_DONE, borrowIds);
        if (borrow.size() > 0) {
        	throw new WineCouponsException("所选酒券存在未还款的标，请重新选择！", 1);
        }

        // 请求兑现
        for (long wineCouponsId : wineCouponsIds) {
			long[] wcIds = {wineCouponsId};
			cashWineCouponsExchange(wcIds, toUser.getUserId());
		}
        printWebResult(MessageUtil.getMessage("MS101002003"), true);
    }
    
    /**
     * PS 现金酒券兑换酒
     *
     * @throws Exception
     */
    @Action("/member/redpacket/wineExchange")
    public void wineExchange() throws Exception {
    	User toUser = getSessionUser();
    	
    	UserIdentify ui = userIdentifyService.getUserIdentifyByUserId(toUser.getUserId());
    	String tppUserCustId = UserUtils.getUserTppCustId(toUser.getUserId());
    	if (ui.getRealNameStatus() != 1 || StringUtil.isBlank(tppUserCustId)) {
    		throw new WineCouponsException("您还未开通第三方账户，请先开户！", 1);
    	}
    	//验证用户收货地址
    	/*List<ReceivingInfoModel> receivingInfoModels = receivingInfoService.ListModel(toUser);
    	if (null == receivingInfoModels || receivingInfoModels.size() == 0) {
    		throw new WineCouponsException("请先填写收货地址！", WineCouponsException.TYPE_JSON);
    	}*/
    	if (StringUtil.isBlank(model.getWineCouponsIds())) {
    		throw new WineCouponsException("请先选择酒券！", 1);
    	}
    	if (model.getWineCouponsIds().length % 6 != 0) {
    		throw new WineCouponsException("请选择6或6的倍数的酒卡！", 1);
    	}
    	cashwineExchange(model.getWineCouponsIds(), toUser);
    	printWebResult(MessageUtil.getMessage("MS101002003"), true);
    }

    /**
     * 酒券兑现补单(代收)
     */
    @Action(NotifyUrl.RE_RED_ENVELOPE_COLLECT_REQ_URL)
    public void wineCouponsExchangeCollect() {
        String token = paramString("token");
        if (!NotifyUrl.RE_CALL_TOKEN.equalsIgnoreCase(token)) {
            throw new WineCouponsException("补单令牌不正确,无法操作!", WineCouponsException.TYPE_JSON);
        }

        long userId = paramLong("user_id");
        if (userId == 0) {
            throw new WineCouponsException("用户ID不能为空!", WineCouponsException.TYPE_JSON);
        }

        User toUser = userService.getUserById(userId);
        if (toUser == null) {
            throw new WineCouponsException("该用户不存在!", WineCouponsException.TYPE_JSON);
        }

        int redType = paramInt("red_type");
        if (redType != WineCouponsType.CASH && redType != WineCouponsType.VIRTUAL) {
            throw new WineCouponsException("酒券类型不正确!type=" + redType, WineCouponsException.TYPE_JSON);
        }

        String redIdStrings = paramString("red_ids");
        if (StringUtil.isEmpty(redIdStrings)) {
            throw new WineCouponsException("酒券ID不能为空!", WineCouponsException.TYPE_JSON);
        }

        // 酒券IDS
        List<String> redIdList = Splitter.on(",").omitEmptyStrings().splitToList(redIdStrings);
        int size = redIdList == null ? 0 : redIdList.size();
        long[] redIds = new long[size];
        if (size > 0) {
            for (int i = 0; i < size; i++) {
                redIds[i] = Long.valueOf(redIdList.get(i));
            }
            try {
                if (WineCouponsType.CASH == redType) {
                    cashWineCouponsExchange(redIds, toUser.getUserId());
                } else if (WineCouponsType.VIRTUAL == redType) {
                    virtualWineCouponsExchange(redIds, toUser.getUserId());
                } else {
                    // nothing
                }
            } catch (Exception e) {
                throw new WineCouponsException("补单失败!", WineCouponsException.TYPE_JSON);
            }
        } else {
            throw new WineCouponsException("没有可兑现酒券!", WineCouponsException.TYPE_JSON);
        }
        try {
            printWebResult("补单成功", true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 现金酒券兑现
     */
    private void cashwineExchange(long[] wineCouponsIds, User exchangeUser) {
    	// 发放商品
    	int length = wineCouponsIds.length / 6;
    	for (int i = 0; i < length; i++) {// 6张酒券兑换一箱酒
			long wineCouponsId = wineCouponsIds[0];// 默认取第一条
			QueryParam queryParam = QueryParam.getInstance();
	        queryParam.addParam("id", wineCouponsId);
			List<UserWineCoupons> wineCouponsList = userWineCouponsDao.findByCriteria(queryParam);
			UserWineCoupons wineCoupons = wineCouponsList.get(0);
	    	BaseGiveAwardModel baseGiveAwardModel = new BaseGiveAwardModel(exchangeUser, wineCoupons.getAmount(), EnumWineCouponsIdsType.WINE_EXCHANGE.getValue(), 0, "酒券兑换");
	    	// 获取商品id
	    	QueryParam queryParam2 = QueryParam.getInstance();
	    	queryParam2.addParam("category", wineCoupons.getKeyId());
	    	AdditionalCommodity additionalCommodity = additionalCommodityDao.findByCriteria(queryParam2).get(0);
	    	if (StringUtil.isBlank(additionalCommodity)) {
	    		throw new WineCouponsException("酒已售罄!", WineCouponsException.TYPE_JSON);
	    	}
	    	baseGiveAwardModel.setRuleId(additionalCommodity.getId());
	    	giveUserCommodityService.giveSingleUserAward(baseGiveAwardModel);
		}
    	
    	// 酒券更新为已使用
    	for (int i = 0; i < wineCouponsIds.length; i++) {
    		long userWineCouponsId = wineCouponsIds[i];
	    	userWineCouponsService.updateStatus(userWineCouponsId, UserWineCouponsStatus.USE, UserWineCouponsStatus.NO_USE);
		}
    }
    
    /**
     * 现金酒券兑现
     */
    private void cashWineCouponsExchange(long[] wineCouponsIds, long exchangeUserId) {
        TppTradeLog tppTradeLog = collectService.createOrder(wineCouponsIds, exchangeUserId, WineCouponsType.CASH, WineCouponsUseType.EXCHANGE_AMOUNT);
        ReturnResult returnResult = collectService.requestOrder(tppTradeLog);
        if (returnResult.isError()) {
            throw new WineCouponsException("酒券兑现失败!", WineCouponsException.TYPE_JSON);
        }
    }

    /**
     * 虚拟酒券兑现
     */
    private void virtualWineCouponsExchange(long[] wineCouponsIds, long exchangeUserId) {
        TppTradeLog tppTradeLog = collectService.createOrder(wineCouponsIds, exchangeUserId, WineCouponsType.VIRTUAL, RedUseType.EXCHANGE_AMOUNT);
        ReturnResult returnResult = collectService.requestOrder(tppTradeLog);
        if (returnResult.isError()) {
            throw new WineCouponsException("酒券兑现失败!", WineCouponsException.TYPE_JSON);
        }
    }

    /**
     * 把酒券的long数据转成酒券list
     *
     * @param wineCouponsIds 酒券IDS
     */
    private List<Long> getWineCouponsIdList(long[] wineCouponsIds) {
        List<Long> ids = new ArrayList<Long>(wineCouponsIds.length);
        for (long wineCouponsId : wineCouponsIds) {
            ids.add(wineCouponsId);
        }
        return ids;
    }
    
    /**
     * 把酒券list数据转成酒券List<Long>（关联的标id）
     *
     * @param wineCouponsList 酒券List
     */
    private List<Long> getBorrowIdList(List<UserWineCoupons> wineCouponsList) {
    	List<Long> ids = new ArrayList<Long>(wineCouponsList.size());
    	for (UserWineCoupons wineCoupon : wineCouponsList) {
    		long borrowId = wineCoupon.getVersion();// 关联的标id
    		ids.add(borrowId);
    	}
    	return ids;
    }
}
